home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 November / Chip Kasım 2000.iso / prog / kasim / 17 / setup.exe / UnixCrypt.pm < prev    next >
Encoding:
Perl POD Document  |  2000-02-24  |  23.9 KB  |  750 lines

  1. package UnixCrypt;
  2.  
  3. use 5.004;  # i.e. not tested under earlier versions
  4. use strict;
  5. use vars qw($VERSION @ISA @EXPORT $OVERRIDE_BUILTIN);
  6.  
  7. $VERSION = '1.0';
  8.  
  9. require Exporter;
  10. @ISA = qw(Exporter);
  11.  
  12. # Don't override built-in crypt() unless forced to to so
  13. use Config;
  14. @EXPORT = qw(crypt)
  15.     if !defined $Config{d_crypt} ||
  16.        (defined $OVERRIDE_BUILTIN && $OVERRIDE_BUILTIN);
  17.  
  18.  
  19. my $ITERATIONS = 16;
  20.  
  21. my @con_salt =
  22. (
  23.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  24.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  25.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  26.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  27.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  28.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
  29.     0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
  30.     0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 
  31.     0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 
  32.     0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 
  33.     0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 
  34.     0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, 
  35.     0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 
  36.     0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 
  37.     0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 
  38.     0x3D, 0x3E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 
  39. );
  40.  
  41. my @shifts2 =
  42. (
  43.     0, 0, 1, 1, 1, 1, 1, 1,
  44.     0, 1, 1, 1, 1, 1, 1, 0
  45. );
  46.  
  47. my @skb0 =
  48. (
  49.     # for C bits (numbered as per FIPS 46) 1 2 3 4 5 6
  50.     0x00000000, 0x00000010, 0x20000000, 0x20000010, 
  51.     0x00010000, 0x00010010, 0x20010000, 0x20010010, 
  52.     0x00000800, 0x00000810, 0x20000800, 0x20000810, 
  53.     0x00010800, 0x00010810, 0x20010800, 0x20010810, 
  54.     0x00000020, 0x00000030, 0x20000020, 0x20000030, 
  55.     0x00010020, 0x00010030, 0x20010020, 0x20010030, 
  56.     0x00000820, 0x00000830, 0x20000820, 0x20000830, 
  57.     0x00010820, 0x00010830, 0x20010820, 0x20010830, 
  58.     0x00080000, 0x00080010, 0x20080000, 0x20080010, 
  59.     0x00090000, 0x00090010, 0x20090000, 0x20090010, 
  60.     0x00080800, 0x00080810, 0x20080800, 0x20080810, 
  61.     0x00090800, 0x00090810, 0x20090800, 0x20090810, 
  62.     0x00080020, 0x00080030, 0x20080020, 0x20080030, 
  63.     0x00090020, 0x00090030, 0x20090020, 0x20090030, 
  64.     0x00080820, 0x00080830, 0x20080820, 0x20080830, 
  65.     0x00090820, 0x00090830, 0x20090820, 0x20090830, 
  66. );
  67. my @skb1 =
  68. (
  69.     # for C bits (numbered as per FIPS 46) 7 8 10 11 12 13
  70.     0x00000000, 0x02000000, 0x00002000, 0x02002000, 
  71.     0x00200000, 0x02200000, 0x00202000, 0x02202000, 
  72.     0x00000004, 0x02000004, 0x00002004, 0x02002004, 
  73.     0x00200004, 0x02200004, 0x00202004, 0x02202004, 
  74.     0x00000400, 0x02000400, 0x00002400, 0x02002400, 
  75.     0x00200400, 0x02200400, 0x00202400, 0x02202400, 
  76.     0x00000404, 0x02000404, 0x00002404, 0x02002404, 
  77.     0x00200404, 0x02200404, 0x00202404, 0x02202404, 
  78.     0x10000000, 0x12000000, 0x10002000, 0x12002000, 
  79.     0x10200000, 0x12200000, 0x10202000, 0x12202000, 
  80.     0x10000004, 0x12000004, 0x10002004, 0x12002004, 
  81.     0x10200004, 0x12200004, 0x10202004, 0x12202004, 
  82.     0x10000400, 0x12000400, 0x10002400, 0x12002400, 
  83.     0x10200400, 0x12200400, 0x10202400, 0x12202400, 
  84.     0x10000404, 0x12000404, 0x10002404, 0x12002404, 
  85.     0x10200404, 0x12200404, 0x10202404, 0x12202404, 
  86. );
  87. my @skb2 =
  88. (
  89.     # for C bits (numbered as per FIPS 46) 14 15 16 17 19 20
  90.     0x00000000, 0x00000001, 0x00040000, 0x00040001, 
  91.     0x01000000, 0x01000001, 0x01040000, 0x01040001, 
  92.     0x00000002, 0x00000003, 0x00040002, 0x00040003, 
  93.     0x01000002, 0x01000003, 0x01040002, 0x01040003, 
  94.     0x00000200, 0x00000201, 0x00040200, 0x00040201, 
  95.     0x01000200, 0x01000201, 0x01040200, 0x01040201, 
  96.     0x00000202, 0x00000203, 0x00040202, 0x00040203, 
  97.     0x01000202, 0x01000203, 0x01040202, 0x01040203, 
  98.     0x08000000, 0x08000001, 0x08040000, 0x08040001, 
  99.     0x09000000, 0x09000001, 0x09040000, 0x09040001, 
  100.     0x08000002, 0x08000003, 0x08040002, 0x08040003, 
  101.     0x09000002, 0x09000003, 0x09040002, 0x09040003, 
  102.     0x08000200, 0x08000201, 0x08040200, 0x08040201, 
  103.     0x09000200, 0x09000201, 0x09040200, 0x09040201, 
  104.     0x08000202, 0x08000203, 0x08040202, 0x08040203, 
  105.     0x09000202, 0x09000203, 0x09040202, 0x09040203, 
  106. );
  107. my @skb3 =
  108. (
  109.     # for C bits (numbered as per FIPS 46) 21 23 24 26 27 28
  110.     0x00000000, 0x00100000, 0x00000100, 0x00100100, 
  111.     0x00000008, 0x00100008, 0x00000108, 0x00100108, 
  112.     0x00001000, 0x00101000, 0x00001100, 0x00101100, 
  113.     0x00001008, 0x00101008, 0x00001108, 0x00101108, 
  114.     0x04000000, 0x04100000, 0x04000100, 0x04100100, 
  115.     0x04000008, 0x04100008, 0x04000108, 0x04100108, 
  116.     0x04001000, 0x04101000, 0x04001100, 0x04101100, 
  117.     0x04001008, 0x04101008, 0x04001108, 0x04101108, 
  118.     0x00020000, 0x00120000, 0x00020100, 0x00120100, 
  119.     0x00020008, 0x00120008, 0x00020108, 0x00120108, 
  120.     0x00021000, 0x00121000, 0x00021100, 0x00121100, 
  121.     0x00021008, 0x00121008, 0x00021108, 0x00121108, 
  122.     0x04020000, 0x04120000, 0x04020100, 0x04120100, 
  123.     0x04020008, 0x04120008, 0x04020108, 0x04120108, 
  124.     0x04021000, 0x04121000, 0x04021100, 0x04121100, 
  125.     0x04021008, 0x04121008, 0x04021108, 0x04121108, 
  126. );
  127. my @skb4 =
  128. (
  129.     # for D bits (numbered as per FIPS 46) 1 2 3 4 5 6
  130.     0x00000000, 0x10000000, 0x00010000, 0x10010000, 
  131.     0x00000004, 0x10000004, 0x00010004, 0x10010004, 
  132.     0x20000000, 0x30000000, 0x20010000, 0x30010000, 
  133.     0x20000004, 0x30000004, 0x20010004, 0x30010004, 
  134.     0x00100000, 0x10100000, 0x00110000, 0x10110000, 
  135.     0x00100004, 0x10100004, 0x00110004, 0x10110004, 
  136.     0x20100000, 0x30100000, 0x20110000, 0x30110000, 
  137.     0x20100004, 0x30100004, 0x20110004, 0x30110004, 
  138.     0x00001000, 0x10001000, 0x00011000, 0x10011000, 
  139.     0x00001004, 0x10001004, 0x00011004, 0x10011004, 
  140.     0x20001000, 0x30001000, 0x20011000, 0x30011000, 
  141.     0x20001004, 0x30001004, 0x20011004, 0x30011004, 
  142.     0x00101000, 0x10101000, 0x00111000, 0x10111000, 
  143.     0x00101004, 0x10101004, 0x00111004, 0x10111004, 
  144.     0x20101000, 0x30101000, 0x20111000, 0x30111000, 
  145.     0x20101004, 0x30101004, 0x20111004, 0x30111004, 
  146. );
  147. my @skb5 =
  148. (
  149.     # for D bits (numbered as per FIPS 46) 8 9 11 12 13 14
  150.     0x00000000, 0x08000000, 0x00000008, 0x08000008, 
  151.     0x00000400, 0x08000400, 0x00000408, 0x08000408, 
  152.     0x00020000, 0x08020000, 0x00020008, 0x08020008, 
  153.     0x00020400, 0x08020400, 0x00020408, 0x08020408, 
  154.     0x00000001, 0x08000001, 0x00000009, 0x08000009, 
  155.     0x00000401, 0x08000401, 0x00000409, 0x08000409, 
  156.     0x00020001, 0x08020001, 0x00020009, 0x08020009, 
  157.     0x00020401, 0x08020401, 0x00020409, 0x08020409, 
  158.     0x02000000, 0x0A000000, 0x02000008, 0x0A000008, 
  159.     0x02000400, 0x0A000400, 0x02000408, 0x0A000408, 
  160.     0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 
  161.     0x02020400, 0x0A020400, 0x02020408, 0x0A020408, 
  162.     0x02000001, 0x0A000001, 0x02000009, 0x0A000009, 
  163.     0x02000401, 0x0A000401, 0x02000409, 0x0A000409, 
  164.     0x02020001, 0x0A020001, 0x02020009, 0x0A020009, 
  165.     0x02020401, 0x0A020401, 0x02020409, 0x0A020409, 
  166. );
  167. my @skb6 =
  168. (
  169.     # for D bits (numbered as per FIPS 46) 16 17 18 19 20 21
  170.     0x00000000, 0x00000100, 0x00080000, 0x00080100, 
  171.     0x01000000, 0x01000100, 0x01080000, 0x01080100, 
  172.     0x00000010, 0x00000110, 0x00080010, 0x00080110, 
  173.     0x01000010, 0x01000110, 0x01080010, 0x01080110, 
  174.     0x00200000, 0x00200100, 0x00280000, 0x00280100, 
  175.     0x01200000, 0x01200100, 0x01280000, 0x01280100, 
  176.     0x00200010, 0x00200110, 0x00280010, 0x00280110, 
  177.     0x01200010, 0x01200110, 0x01280010, 0x01280110, 
  178.     0x00000200, 0x00000300, 0x00080200, 0x00080300, 
  179.     0x01000200, 0x01000300, 0x01080200, 0x01080300, 
  180.     0x00000210, 0x00000310, 0x00080210, 0x00080310, 
  181.     0x01000210, 0x01000310, 0x01080210, 0x01080310, 
  182.     0x00200200, 0x00200300, 0x00280200, 0x00280300, 
  183.     0x01200200, 0x01200300, 0x01280200, 0x01280300, 
  184.     0x00200210, 0x00200310, 0x00280210, 0x00280310, 
  185.     0x01200210, 0x01200310, 0x01280210, 0x01280310, 
  186. );
  187. my @skb7 =
  188. (
  189.     # for D bits (numbered as per FIPS 46) 22 23 24 25 27 28
  190.     0x00000000, 0x04000000, 0x00040000, 0x04040000, 
  191.     0x00000002, 0x04000002, 0x00040002, 0x04040002, 
  192.     0x00002000, 0x04002000, 0x00042000, 0x04042000, 
  193.     0x00002002, 0x04002002, 0x00042002, 0x04042002, 
  194.     0x00000020, 0x04000020, 0x00040020, 0x04040020, 
  195.     0x00000022, 0x04000022, 0x00040022, 0x04040022, 
  196.     0x00002020, 0x04002020, 0x00042020, 0x04042020, 
  197.     0x00002022, 0x04002022, 0x00042022, 0x04042022, 
  198.     0x00000800, 0x04000800, 0x00040800, 0x04040800, 
  199.     0x00000802, 0x04000802, 0x00040802, 0x04040802, 
  200.     0x00002800, 0x04002800, 0x00042800, 0x04042800, 
  201.     0x00002802, 0x04002802, 0x00042802, 0x04042802, 
  202.     0x00000820, 0x04000820, 0x00040820, 0x04040820, 
  203.     0x00000822, 0x04000822, 0x00040822, 0x04040822, 
  204.     0x00002820, 0x04002820, 0x00042820, 0x04042820, 
  205.     0x00002822, 0x04002822, 0x00042822, 0x04042822, 
  206. );
  207.  
  208. my @SPtrans0 =
  209. (
  210.     # nibble 0
  211.     0x00820200, 0x00020000, 0x80800000, 0x80820200,
  212.     0x00800000, 0x80020200, 0x80020000, 0x80800000,
  213.     0x80020200, 0x00820200, 0x00820000, 0x80000200,
  214.     0x80800200, 0x00800000, 0x00000000, 0x80020000,
  215.     0x00020000, 0x80000000, 0x00800200, 0x00020200,
  216.     0x80820200, 0x00820000, 0x80000200, 0x00800200,
  217.     0x80000000, 0x00000200, 0x00020200, 0x80820000,
  218.     0x00000200, 0x80800200, 0x80820000, 0x00000000,
  219.     0x00000000, 0x80820200, 0x00800200, 0x80020000,
  220.     0x00820200, 0x00020000, 0x80000200, 0x00800200,
  221.     0x80820000, 0x00000200, 0x00020200, 0x80800000,
  222.     0x80020200, 0x80000000, 0x80800000, 0x00820000,
  223.     0x80820200, 0x00020200, 0x00820000, 0x80800200,
  224.     0x00800000, 0x80000200, 0x80020000, 0x00000000,
  225.     0x00020000, 0x00800000, 0x80800200, 0x00820200,
  226.     0x80000000, 0x80820000, 0x00000200, 0x80020200,
  227. );
  228. my @SPtrans1 =
  229. (
  230.     # nibble 1
  231.     0x10042004, 0x00000000, 0x00042000, 0x10040000,
  232.     0x10000004, 0x00002004, 0x10002000, 0x00042000,
  233.     0x00002000, 0x10040004, 0x00000004, 0x10002000,
  234.     0x00040004, 0x10042000, 0x10040000, 0x00000004,
  235.     0x00040000, 0x10002004, 0x10040004, 0x00002000,
  236.     0x00042004, 0x10000000, 0x00000000, 0x00040004,
  237.     0x10002004, 0x00042004, 0x10042000, 0x10000004,
  238.     0x10000000, 0x00040000, 0x00002004, 0x10042004,
  239.     0x00040004, 0x10042000, 0x10002000, 0x00042004,
  240.     0x10042004, 0x00040004, 0x10000004, 0x00000000,
  241.     0x10000000, 0x00002004, 0x00040000, 0x10040004,
  242.     0x00002000, 0x10000000, 0x00042004, 0x10002004,
  243.     0x10042000, 0x00002000, 0x00000000, 0x10000004,
  244.     0x00000004, 0x10042004, 0x00042000, 0x10040000,
  245.     0x10040004, 0x00040000, 0x00002004, 0x10002000,
  246.     0x10002004, 0x00000004, 0x10040000, 0x00042000,
  247. );
  248. my @SPtrans2 =
  249. (
  250.     # nibble 2
  251.     0x41000000, 0x01010040, 0x00000040, 0x41000040,
  252.     0x40010000, 0x01000000, 0x41000040, 0x00010040,
  253.     0x01000040, 0x00010000, 0x01010000, 0x40000000,
  254.     0x41010040, 0x40000040, 0x40000000, 0x41010000,
  255.     0x00000000, 0x40010000, 0x01010040, 0x00000040,
  256.     0x40000040, 0x41010040, 0x00010000, 0x41000000,
  257.     0x41010000, 0x01000040, 0x40010040, 0x01010000,
  258.     0x00010040, 0x00000000, 0x01000000, 0x40010040,
  259.     0x01010040, 0x00000040, 0x40000000, 0x00010000,
  260.     0x40000040, 0x40010000, 0x01010000, 0x41000040,
  261.     0x00000000, 0x01010040, 0x00010040, 0x41010000,
  262.     0x40010000, 0x01000000, 0x41010040, 0x40000000,
  263.     0x40010040, 0x41000000, 0x01000000, 0x41010040,
  264.     0x00010000, 0x01000040, 0x41000040, 0x00010040,
  265.     0x01000040, 0x00000000, 0x41010000, 0x40000040,
  266.     0x41000000, 0x40010040, 0x00000040, 0x01010000,
  267. );
  268. my @SPtrans3 =
  269. (
  270.     # nibble 3
  271.     0x00100402, 0x04000400, 0x00000002, 0x04100402,
  272.     0x00000000, 0x04100000, 0x04000402, 0x00100002,
  273.     0x04100400, 0x04000002, 0x04000000, 0x00000402,
  274.     0x04000002, 0x00100402, 0x00100000, 0x04000000,
  275.     0x04100002, 0x00100400, 0x00000400, 0x00000002,
  276.     0x00100400, 0x04000402, 0x04100000, 0x00000400,
  277.     0x00000402, 0x00000000, 0x00100002, 0x04100400,
  278.     0x04000400, 0x04100002, 0x04100402, 0x00100000,
  279.     0x04100002, 0x00000402, 0x00100000, 0x04000002,
  280.     0x00100400, 0x04000400, 0x00000002, 0x04100000,
  281.     0x04000402, 0x00000000, 0x00000400, 0x00100002,
  282.     0x00000000, 0x04100002, 0x04100400, 0x00000400,
  283.     0x04000000, 0x04100402, 0x00100402, 0x00100000,
  284.     0x04100402, 0x00000002, 0x04000400, 0x00100402,
  285.     0x00100002, 0x00100400, 0x04100000, 0x04000402,
  286.     0x00000402, 0x04000000, 0x04000002, 0x04100400,
  287. );
  288. my @SPtrans4 =
  289. (
  290.     # nibble 4
  291.     0x02000000, 0x00004000, 0x00000100, 0x02004108,
  292.     0x02004008, 0x02000100, 0x00004108, 0x02004000,
  293.     0x00004000, 0x00000008, 0x02000008, 0x00004100,
  294.     0x02000108, 0x02004008, 0x02004100, 0x00000000,
  295.     0x00004100, 0x02000000, 0x00004008, 0x00000108,
  296.     0x02000100, 0x00004108, 0x00000000, 0x02000008,
  297.     0x00000008, 0x02000108, 0x02004108, 0x00004008,
  298.     0x02004000, 0x00000100, 0x00000108, 0x02004100,
  299.     0x02004100, 0x02000108, 0x00004008, 0x02004000,
  300.     0x00004000, 0x00000008, 0x02000008, 0x02000100,
  301.     0x02000000, 0x00004100, 0x02004108, 0x00000000,
  302.     0x00004108, 0x02000000, 0x00000100, 0x00004008,
  303.     0x02000108, 0x00000100, 0x00000000, 0x02004108,
  304.     0x02004008, 0x02004100, 0x00000108, 0x00004000,
  305.     0x00004100, 0x02004008, 0x02000100, 0x00000108,
  306.     0x00000008, 0x00004108, 0x02004000, 0x02000008,
  307. );
  308. my @SPtrans5 =
  309. (
  310.     # nibble 5
  311.     0x20000010, 0x00080010, 0x00000000, 0x20080800,
  312.     0x00080010, 0x00000800, 0x20000810, 0x00080000,
  313.     0x00000810, 0x20080810, 0x00080800, 0x20000000,
  314.     0x20000800, 0x20000010, 0x20080000, 0x00080810,
  315.     0x00080000, 0x20000810, 0x20080010, 0x00000000,
  316.     0x00000800, 0x00000010, 0x20080800, 0x20080010,
  317.     0x20080810, 0x20080000, 0x20000000, 0x00000810,
  318.     0x00000010, 0x00080800, 0x00080810, 0x20000800,
  319.     0x00000810, 0x20000000, 0x20000800, 0x00080810,
  320.     0x20080800, 0x00080010, 0x00000000, 0x20000800,
  321.     0x20000000, 0x00000800, 0x20080010, 0x00080000,
  322.     0x00080010, 0x20080810, 0x00080800, 0x00000010,
  323.     0x20080810, 0x00080800, 0x00080000, 0x20000810,
  324.     0x20000010, 0x20080000, 0x00080810, 0x00000000,
  325.     0x00000800, 0x20000010, 0x20000810, 0x20080800,
  326.     0x20080000, 0x00000810, 0x00000010, 0x20080010,
  327. );
  328. my @SPtrans6 =
  329. (
  330.     # nibble 6
  331.     0x00001000, 0x00000080, 0x00400080, 0x00400001,
  332.     0x00401081, 0x00001001, 0x00001080, 0x00000000,
  333.     0x00400000, 0x00400081, 0x00000081, 0x00401000,
  334.     0x00000001, 0x00401080, 0x00401000, 0x00000081,
  335.     0x00400081, 0x00001000, 0x00001001, 0x00401081,
  336.     0x00000000, 0x00400080, 0x00400001, 0x00001080,
  337.     0x00401001, 0x00001081, 0x00401080, 0x00000001,
  338.     0x00001081, 0x00401001, 0x00000080, 0x00400000,
  339.     0x00001081, 0x00401000, 0x00401001, 0x00000081,
  340.     0x00001000, 0x00000080, 0x00400000, 0x00401001,
  341.     0x00400081, 0x00001081, 0x00001080, 0x00000000,
  342.     0x00000080, 0x00400001, 0x00000001, 0x00400080,
  343.     0x00000000, 0x00400081, 0x00400080, 0x00001080,
  344.     0x00000081, 0x00001000, 0x00401081, 0x00400000,
  345.     0x00401080, 0x00000001, 0x00001001, 0x00401081,
  346.     0x00400001, 0x00401080, 0x00401000, 0x00001001,
  347. );
  348. my @SPtrans7 =
  349. (
  350.     # nibble 7
  351.     0x08200020, 0x08208000, 0x00008020, 0x00000000,
  352.     0x08008000, 0x00200020, 0x08200000, 0x08208020,
  353.     0x00000020, 0x08000000, 0x00208000, 0x00008020,
  354.     0x00208020, 0x08008020, 0x08000020, 0x08200000,
  355.     0x00008000, 0x00208020, 0x00200020, 0x08008000,
  356.     0x08208020, 0x08000020, 0x00000000, 0x00208000,
  357.     0x08000000, 0x00200000, 0x08008020, 0x08200020,
  358.     0x00200000, 0x00008000, 0x08208000, 0x00000020,
  359.     0x00200000, 0x00008000, 0x08000020, 0x08208020,
  360.     0x00008020, 0x08000000, 0x00000000, 0x00208000,
  361.     0x08200020, 0x08008020, 0x08008000, 0x00200020,
  362.     0x08208000, 0x00000020, 0x00200020, 0x08008000,
  363.     0x08208020, 0x00200000, 0x08200000, 0x08000020,
  364.     0x00208000, 0x00008020, 0x08008020, 0x08200000,
  365.     0x00000020, 0x08208000, 0x00208020, 0x00000000,
  366.     0x08000000, 0x08200020, 0x00008000, 0x00208020
  367. );
  368.  
  369. my @cov_2char =
  370. (
  371.     0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 
  372.     0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 
  373.     0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 
  374.     0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 
  375.     0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 
  376.     0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 
  377.     0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 
  378.     0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
  379. );
  380.  
  381. sub ushr  # only for ints! (mimics the Java >>> operator)
  382. {
  383.     my ($n, $s) = @_;
  384.  
  385.     $s &= 0x1f;
  386.  
  387.     return( ($n >> $s) & (~0 >> $s) );
  388. }
  389.  
  390. sub toByte
  391. {
  392.     my $value = shift;
  393.  
  394.     $value &= 0xff;
  395.     $value = - ((~$value & 0xff) + 1)
  396.         if $value & 0x80;
  397.  
  398.     return $value;
  399. }
  400.  
  401. sub toInt
  402. {
  403.     my $value = shift;
  404.  
  405.     $value = - ((~$value & 0xffffffff) + 1)
  406.         if $value & 0x80000000;
  407.  
  408.     return $value;
  409. }
  410.  
  411. sub byteToUnsigned # int byteToUnsigned(byte b)
  412. {
  413.     my $value = shift;
  414.  
  415.     return( $value >= 0 ? $value : $value + 256 );
  416. }
  417.  
  418. sub fourBytesToInt # int fourBytesToInt(byte b[], int offset)
  419. {
  420.     my ($b, $offset) = @_;
  421.     my $value;
  422.  
  423.     $value  =  byteToUnsigned($b->[$offset++]);
  424.     $value |= (byteToUnsigned($b->[$offset++]) <<  8);
  425.     $value |= (byteToUnsigned($b->[$offset++]) << 16);
  426.     $value |= (byteToUnsigned($b->[$offset++]) << 24);
  427.  
  428.     return toInt($value);
  429. }
  430.  
  431. sub intToFourBytes # void intToFourBytes(int iValue, byte b[], int offset)
  432. {
  433.     my ($iValue, $b, $offset) = @_;
  434.  
  435.     $b->[$offset++] = toByte(ushr($iValue, 0) & 0xff);
  436.     $b->[$offset++] = toByte(ushr($iValue, 8) & 0xff);
  437.     $b->[$offset++] = toByte(ushr($iValue,16) & 0xff);
  438.     $b->[$offset++] = toByte(ushr($iValue,24) & 0xff);
  439.  
  440.     return undef;
  441. }
  442.  
  443. sub PERM_OP # void PERM_OP(int a, int b, int n, int m, int results[])
  444. {
  445.     my ($a, $b, $n, $m, $results) = @_;
  446.     my $t;
  447.  
  448.     $t = (ushr($a,$n) ^ $b) & $m;
  449.     $a ^= $t << $n;
  450.     $b ^= $t;
  451.  
  452.     $results->[0] = toInt($a);
  453.     $results->[1] = toInt($b);
  454.  
  455.     return undef;
  456. }
  457.  
  458. sub HPERM_OP # void HPERM_OP(int a, int n, int m)
  459. {
  460.     my ($a, $n, $m) = @_;
  461.     my $t;
  462.  
  463.     $t = (($a << (16 - $n)) ^ $a) & $m;
  464.     $a = $a ^ $t ^ ushr($t, 16 - $n);
  465.  
  466.     return toInt($a);
  467. }
  468.  
  469. sub des_set_key # int [] des_set_key(byte key[])
  470. {
  471.     my ($key) = @_;
  472.     my @schedule; $#schedule = $ITERATIONS * 2 -1;
  473.  
  474.     my $c = fourBytesToInt($key, 0);
  475.     my $d = fourBytesToInt($key, 4);
  476.  
  477.     my @results; $#results = 1;
  478.  
  479.     PERM_OP($d, $c, 4, 0x0f0f0f0f, \@results);
  480.     $d = $results[0]; $c = $results[1];
  481.  
  482.     $c = HPERM_OP($c, -2, 0xcccc0000);
  483.     $d = HPERM_OP($d, -2, 0xcccc0000);
  484.  
  485.     PERM_OP($d, $c, 1, 0x55555555, \@results);
  486.     $d = $results[0]; $c = $results[1];
  487.  
  488.     PERM_OP($c, $d, 8, 0x00ff00ff, \@results);
  489.     $c = $results[0]; $d = $results[1];
  490.  
  491.     PERM_OP($d, $c, 1, 0x55555555, \@results);
  492.     $d = $results[0]; $c = $results[1];
  493.  
  494.     $d = (    (($d & 0x000000ff) << 16) |     ($d & 0x0000ff00)  |
  495.            ushr($d & 0x00ff0000,    16) | ushr($c & 0xf0000000, 4));
  496.     $c &= 0x0fffffff;
  497.  
  498.     my ($s, $t);
  499.     my ($i, $j);
  500.  
  501.     $j = 0;
  502.     for($i = 0; $i < $ITERATIONS; $i++)
  503.     {
  504.         if($shifts2[$i])
  505.         {
  506.             $c = ushr($c, 2) | ($c << 26);
  507.             $d = ushr($d, 2) | ($d << 26);
  508.         }
  509.         else
  510.         {
  511.             $c = ushr($c, 1) | ($c << 27);
  512.             $d = ushr($d, 1) | ($d << 27);
  513.         }
  514.  
  515.         $c &= 0x0fffffff;
  516.         $d &= 0x0fffffff;
  517.  
  518.         $s = $skb0[     ($c   ) & 0x3f                        ]|
  519.              $skb1[(ushr($c, 6) & 0x03) | (ushr($c, 7) & 0x3c)]|
  520.              $skb2[(ushr($c,13) & 0x0f) | (ushr($c,14) & 0x30)]|
  521.              $skb3[(ushr($c,20) & 0x01) | (ushr($c,21) & 0x06) |
  522.                                           (ushr($c,22) & 0x38)];
  523.  
  524.         $t = $skb4[     ($d   ) & 0x3f                         ]|
  525.              $skb5[(ushr($d, 7) & 0x03) | (ushr($d, 8) & 0x3c) ]|
  526.              $skb6[ ushr($d,15) & 0x3f                         ]|
  527.              $skb7[(ushr($d,21) & 0x0f) | (ushr($d,22) & 0x30)];
  528.  
  529.         $schedule[$j++] = (    ($t << 16) | ($s & 0x0000ffff)) & 0xffffffff;
  530.         $s              = (ushr($s,   16) | ($t & 0xffff0000));
  531.  
  532.         $s              = ($s << 4) | ushr($s,28);
  533.         $schedule[$j++] = $s & 0xffffffff;
  534.     }
  535.  
  536.     return \@schedule;
  537. }
  538.  
  539. sub D_ENCRYPT # int D_ENCRYPT(int L, int R, int S, int E0, int E1, int s[])
  540. {
  541.     my ($L, $R, $S, $E0, $E1, $s) = @_;
  542.     my ($t, $u, $v);
  543.  
  544.     $v = $R ^ ushr($R,16);
  545.     $u = $v & $E0;
  546.     $v = $v & $E1;
  547.     $u = ($u ^ ($u << 16)) ^ $R ^ $s->[$S];
  548.     $t = ($v ^ ($v << 16)) ^ $R ^ $s->[$S + 1];
  549.     $t = ushr($t, 4) | ($t << 28);
  550.  
  551.     $L ^= $SPtrans1[    ($t    ) & 0x3f] |
  552.           $SPtrans3[ushr($t,  8) & 0x3f] |
  553.           $SPtrans5[ushr($t, 16) & 0x3f] |
  554.           $SPtrans7[ushr($t, 24) & 0x3f] |
  555.           $SPtrans0[    ($u    ) & 0x3f] |
  556.           $SPtrans2[ushr($u,  8) & 0x3f] |
  557.           $SPtrans4[ushr($u, 16) & 0x3f] |
  558.           $SPtrans6[ushr($u, 24) & 0x3f];
  559.  
  560.     return $L;
  561. }
  562.  
  563. sub body # int [] body(int schedule[], int Eswap0, int Eswap1)
  564. {
  565.     my ($schedule, $Eswap0, $Eswap1) = @_;
  566.     my $left  = 0;
  567.     my $right = 0;
  568.     my $t     = 0;
  569.  
  570.     my ($i, $j);
  571.     for($j = 0; $j < 25; $j++)
  572.     {
  573.         for($i = 0; $i < $ITERATIONS * 2; $i += 4)
  574.         {
  575.             $left  = D_ENCRYPT($left,  $right, $i,     $Eswap0, $Eswap1, $schedule);
  576.             $right = D_ENCRYPT($right, $left,  $i + 2, $Eswap0, $Eswap1, $schedule);
  577.         }
  578.         $t     = $left; 
  579.         $left  = $right; 
  580.         $right = $t;
  581.     }
  582.  
  583.     $t = $right;
  584.  
  585.     $right = ushr($left, 1) | ($left << 31);
  586.     $left  = ushr($t   , 1) | ($t    << 31);
  587.  
  588.     $left  &= 0xffffffff;
  589.     $right &= 0xffffffff;
  590.  
  591.     my @results; $#results = 1;
  592.  
  593.     PERM_OP($right, $left, 1, 0x55555555, \@results); 
  594.     $right = $results[0]; $left = $results[1];
  595.  
  596.     PERM_OP($left, $right, 8, 0x00ff00ff, \@results); 
  597.     $left = $results[0]; $right = $results[1];
  598.  
  599.     PERM_OP($right, $left, 2, 0x33333333, \@results); 
  600.     $right = $results[0]; $left = $results[1];
  601.  
  602.     PERM_OP($left, $right, 16, 0x0000ffff, \@results);
  603.     $left = $results[0]; $right = $results[1];
  604.  
  605.     PERM_OP($right, $left, 4, 0x0f0f0f0f, \@results);
  606.     $right = $results[0]; $left = $results[1];
  607.  
  608.     my @out; $#out = 1;
  609.  
  610.     $out[0] = $left; $out[1] = $right;
  611.  
  612.     return \@out;
  613. }
  614.  
  615. sub crypt($$) # String crypt(String plaintext, String salt)
  616. {
  617.     my ($plaintext, $salt) = @_;
  618.     my $buffer = '';
  619.  
  620.     return $buffer if !defined $salt || $salt eq '';
  621.  
  622.     $salt .= $salt if length $salt < 2;
  623.     $plaintext = '' if !defined $plaintext;
  624.  
  625.     $buffer = substr $salt,0,2;
  626.  
  627.     my $Eswap0 = $con_salt[ord(substr $salt,0,1)];
  628.     my $Eswap1 = $con_salt[ord(substr $salt,1,1)] << 4;
  629.  
  630.     my @key;
  631.     @key[0..7] = (0) x 8;
  632.  
  633.     my @iChar = map { ord($_) << 1 } split(//, $plaintext);
  634.     my $i;
  635.     for (my $i = 0; $i < @key && $i < @iChar; $i++) {
  636.         $key[$i] = toByte($iChar[$i]);
  637.     }
  638.  
  639.     my $schedule = des_set_key(\@key);
  640.     my $out      = body($schedule, $Eswap0, $Eswap1);
  641.  
  642.     my @b; $#b = 8;
  643.  
  644.     intToFourBytes($out->[0], \@b, 0);
  645.     intToFourBytes($out->[1], \@b, 4);
  646.     $b[8] = 0;
  647.  
  648.     my ($j, $c, $y, $u);
  649.     for($i = 2, $y = 0, $u = 0x80; $i < 13; $i++)
  650.     {
  651.         for($j = 0, $c = 0; $j < 6; $j++)
  652.         {
  653.             $c <<= 1;
  654.  
  655.             $c |= 1 if ($b[$y] & $u) != 0;
  656.  
  657.             $u >>= 1;
  658.  
  659.             if($u == 0)
  660.             {
  661.                 $y++;
  662.                 $u = 0x80;
  663.             }
  664.         }
  665.         $buffer .= chr($cov_2char[$c]);
  666.     }
  667.  
  668.     return $buffer;
  669. }
  670.  
  671. 1;
  672. __END__
  673.  
  674. =head1 NAME
  675.  
  676. Crypt::UnixCrypt - perl-only implementation of the C<crypt> function.
  677.  
  678. =head1 SYNOPSIS
  679.  
  680.   use Crypt::UnixCrypt;
  681.   $hashed = crypt($plaintext,$salt);
  682.  
  683.   # always use this module's crypt
  684.   BEGIN { $Crypt::UnixCrpyt::OVERRIDE_BUILTIN = 1 }
  685.   use Crypt::UnixCrypt;
  686.  
  687. =head1 DESCRIPTION
  688.  
  689. This module is for all those poor souls whose perl port answers to the
  690. use of C<crypt()> with the message `The crypt() function is unimplemented
  691. due to excessive paranoia.'.
  692.  
  693. This module won't overload a built-in C<crypt()> unless forced by a true
  694. value of the variable C<$Crypt::UnixCrypt::OVERRIDE_BUILTIN>.
  695.  
  696. If you use this module, you probably neither have a built-in C<crypt()>
  697. function nor a L<crypt(3)> manpage; so I'll supply the appropriate portions
  698. of its description (from my Linux system) here:
  699.  
  700. crypt is the password encryption function. It is based on the Data
  701. Encryption Standard algorithm with variations intended (among other
  702. things) to discourage use of hardware implementations of a key search.
  703.  
  704. $plaintext is a user's typed password.
  705.  
  706. $salt is a two-character string chosen from the set [a-zA-Z0-9./]. This
  707. string is used to perturb the algorithm in one of 4096 different ways.
  708.  
  709. By taking the lowest 7 bit of each character of $plaintext (filling it up
  710. to 8 characters with zeros, if needed), a 56-bit key is obtained. This
  711. 56-bit key is used to encrypt repeatedly a constant string (usually a
  712. string consisting of all zeros). The returned value points to the
  713. encrypted password, a series of 13 printable ASCII characters (the first
  714. two characters represent the salt itself).
  715.  
  716. Warning: The key space consists of 2**56 equal 7.2e16 possible values.
  717. Exhaustive searches of this key space are possible using massively
  718. parallel computers. Software, such as crack(1), is available which will
  719. search the portion of this key space that is generally used by humans
  720. for passwords. Hence, password selection should, at minimum, avoid
  721. common words and names. The use of a passwd(1) program that checks for
  722. crackable passwords during the selection process is recommended.
  723.  
  724. The DES algorithm itself has a few quirks which make the use of the
  725. crypt(3) interface a very poor choice for anything other than password
  726. authentication. If you are planning on using the crypt(3) interface for
  727. a cryptography project, don't do it: get a good book on encryption and
  728. one of the widely available DES libraries.
  729.  
  730. =head1 COPYRIGHT
  731.  
  732. This module is free software; you may redistribute it and/or modify it
  733. under the same terms as Perl itself.
  734.  
  735. =head1 AUTHORS
  736.  
  737. Written by Martin Vorlaender, martin@radiogaga.harz.de, 11-DEC-1997.
  738. Based upon Java source code written by jdumas@zgs.com, which in turn is
  739. based upon C source code written by Eric Young, eay@psych.uq.oz.au.
  740.  
  741. =head1 CAVEATS
  742.  
  743. In extreme situations, this function doesn't behave like C<crypt(3)>,
  744. e.g. when called with a salt not in [A-Za-z0-9./]{2}.
  745.  
  746. =head1 SEE ALSO
  747.  
  748. perl(1), perlfunc(1), crypt(3).
  749.  
  750.